←
▼
▲
g("${RootPath}") = "${${Target}/RootPath}"
g("${TargetA/RootPath}") = "C:\FolderA"
g("${TargetB/RootPath}") = "C:\FolderB"
g("${Target}") = "TargetA"
Assert g("${RootPath}") = "C:\FolderA"
g("${Target}") = "TargetB"
Assert g("${RootPath}") = "C:\FolderB"
g("${RootPath}") = "C:\FolderA"
Assert g("${RootPath}") = "C:\FolderA"
元々、下記のように使われていた変数 ${RootPath} があるとします。
変数の値を、別の変数の値によって動的に変えたい場合は、下記のどちらの記述もできます。
g("${RootPath}") = "C:\Folder${Target}"
g("${Target}") = "A"
Assert g("${RootPath}") = "C:\FolderA"
g("${Target}") = "B"
Assert g("${RootPath}") = "C:\FolderB"
g("$\{") = "${" '// $\ は $ に置き換わります
g("$\\") = "$\"
g("$\}") = "$}"
g("$A") = "$A" '// $ の後に { がないと、そのまま
(メモ) このエスケープにより、単純に "${" を検索すれば、それが展開すべき変数かどうかが
分かります。
辞書の値に、辞書のキーへの参照を入れて、遅延評価する辞書です。
LazyDictionaryClass のオブジェクトは名前空間に相当し、キーは変数名に相当します。
Set g = new LazyDictionaryClass
g("${RootPath}") = "C:\Folder${Target}"
g("${Target}") = "A"
Assert g("${RootPath}") = "C:\FolderA"
キーは、${ 〜 } 形式(例: ${A})にしてください。 $〜 形式(例: $A)は、エラーになります。
キーの ${ 〜 } の中に "$", "{", "}" は使えませんが、他の記号、Unicode文字(日本語など)
は使えます。
g("${RootPath( TargetA )}") = "C:\FolderA"
g("${RootPath( TargetB )}") = "C:\FolderB"
target = "TargetA"
Assert g("${RootPath( "+ target +" )}") = "C:\FolderA"
単純な変換関数であれば、関数をデータに置き換えることもできます。
下記の RootPath が、関数の代わりです。
キーが存在しなければ、エラーになります。
テスト
ソース
→ vbslib.vbs
Set g = new LazyDictionaryClass
g("${Array1}") = Array( "${Var}/1", "${Var}/2" )
g("${Array2}") = Array( "${Array1}", "${Var}/3", "${Var}/4", "${Var}/5" )
g("${Var}") = "x"
array1 = g("${Array1}")
array2 = g("${Array2}")
Assert IsSameArray( array1, Array( "x/1", "x/2" ) )
Assert IsSameArray( array2, Array( "x/1", "x/2", "x/3", "x/4", "x/5" ) )
For Each value In g("${Array2}")
echo value
Next
関連
g("${Var}") = True
Assert g("${Var}") = True '// 式ではないので boolean 型のまま
Assert g("Var=${Var}") = "Var=True" '// 式なので文字列に変換
式を参照すると、文字列になります。 式とは、${ } で囲まれた変数以外の文字がある文字列です。
キーの展開は参照時( g("${Var}") を Get するとき)に行われる(遅延評価である)ため、
キーを含むアイテム(値)を設定するときに、そのキーが定義されていなくても構いません。
例:上記 ${Target}。 つまり、連続して設定するときは、設定する順番を問いません。
参照時にキーが存在しないときは、エラーになります。 簡単な文字列変換関数なら、
辞書のデータに置き換えることができます。
→ 関数型プログラミング
Set g = new LazyDictionaryClass
g("${Workspace/Lib}") = "FolderA"
g("${Workspace/Sample}") = "FolderB"
values1 = g.Each_( "${Workspace/${i}}", "${i}", Array( "Lib", "Sample" ) )
Assert IsSameArray( values1, Array( "FolderA", "FolderB" ) )
formulas = g.EachFormula( "${Workspace/${i}}", "${i}", Array( "Lib", "Sample" ) )
Assert IsSameArray( formulas, Array( "${Workspace/Lib}", "${Workspace/Sample}" ) )
values2 = g( formulas )
Assert IsSameArray( values2, values1 )
Each_ や EachFormula を使えば、配列の要素をループ変数のように扱って変換できます。
また、辞書を参照するときに、配列を指定することもできます。
値( = の右)に配列を指定することができます。
また、配列の要素に、配列を値を持つ変数への参照を指定すると、ネストしないで展開されます。
$\{ と書くと、${ という文字列データができます。 この処理は、変数の展開をしないために、
最後に行われます。 展開した結果に $\ があるときは、$ に置き換わります。
→ T_LazyDictionary.vbs
オブジェクトの設定と参照ができます。
Set g("${Var}") = new NameOnlyClass
echo g("${Var}").Name
キーが存在しないときに自動的にキーを追加しないため、文字列のスペルミスを防ぐことができます。
ただし、キーとアイテムが異なることが一般的である辞書型では、アイテムを調べなければ
文字列を知ることができないため、開発効率が落ちます。
そこで、キーの先頭が ">" から、アイテムと同じであるようなルールにするとよいでしょう。
なお、> を選んだ理由は、メールの引用(コピー)記号や、NaturalDocs の空白を維持する記号に
近い意味を持っているからです。
Set g = new LazyDictionaryClass
g("${>Spell}") = "Spell"
Set g = new LazyDictionaryClass
g("${Var1}") = "Value1"
g("${Var2}") = "${Var1}-2"
g.EchoToEditor
EchoToEditor
${Var1} = "Value1"
${Var2} = "${Var1}-2" = "Value1-2"
EchoToEditor メソッドを呼び出すと、アイテムのキーと展開前の値と展開後の値が書かれた
テキスト エディターが開きます。 内容は、GetSetListString の返り値と同じです。
テキスト エディターで開く内容:
patch_path = g("${Repository_workspace}\Sample_Test_patch\patch")
辞書を参照するコードが長くなるときは、役割を説明する説明変数をローカルで(関数内のスコープ
をもつ変数を)活用するとよいでしょう
→ 説明変数
参考
g.DebugMode = True '// [TODO] 追加
g("${Target}") = "B"
echo g("${RootPath}")
下記のように、デバッグ・モードをオンにすると、設定した内容を echo 表示したり、参照時にキーを
1つずつ展開する様子を echo 表示します。
<DictionaryEx operation="Set" key="${Target}">B</DictionaryEx>
<DictionaryEx operation="Get" key="${RootPath}">
<Expand count="1">C:\Folder${Target}</Expand>
<Expand count="2">C:\FolderB</Expand>
</DictionaryEx>
echo 表示の内容:
Set g = new LazyDictionaryClass
Assert g("${USERPROFILE}\Desktop") = "C:\Users\user1\Desktop"
OSの環境変数を参照することもできます。
g("${RootPath}") = "C:\Folder${Target}"
g("${Target}") = "A"
Assert g.Formula("${RootPath}") = "C:\Folder${Target}"
Assert g("${RootPath}") = "C:\FolderA"
遅延評価する前の値を参照するには、Formula プロパティを使います。
関連
Set a = new LazyDictionaryClass
Set b = new LazyDictionaryClass
a.AddDictionary b
Set g = new LazyDictionaryClass
g("${A}") = "AAA"
g("${B}") = "BB"
Assert g.EvaluateReverse( "1AAA2BB3AAA4" ) = "1${A}2${B}3${A}4"
Set g = new LazyDictionaryClass
g("${A3}") = "AAA"
g("${A4}") = "AAAA"
g("${A2}") = "AA"
Assert g.EvaluateReverse( "AAAA" ) = "${A4}"
値の文字列の長さが長い変数に優先的に変換されます。
逆に、変数でない ${ を含む文字列を、${ 〜 } 変数を変換しようとする文字列に入れる場合は、
次の変換をします。
'// "$\" => "$\\", "${" => "$\{"
text = Replace( Replace( text, "$\", "$\\" ), "${", "$\{" )
Set g = new LazyDictionaryClass
echo g(text)
関連
EvaluateReverse
Set g = new LazyDictionaryClass
g("${XA}") = "X:\FolderA"
g("${Extension}") = ".txt"
Assert g.GetStepPath( "X:\FolderA\File.xml", "X:\" ) = "${XA}\File.xml"
Assert g.GetStepPath( "C:\FolderA\File.xml", "C:\FolderA" ) = "File.xml"
Assert g.GetStepPath( "C:\FolderA\File.txt", "C:\FolderA" ) = "File${Extension}"
GetStepPath
GetStepPath メソッドでは、フル パスが格納された変数に戻らなかったときだけ、
指定した基準パスからの相対パスに変換されます。
${> } 形式の記述は、次の関数でも使われています。
特殊な URL 予約文字をエスケープしない
${>#} で、# をファイル名の一部にする
参考
ちなみに、戻した変数を一覧するときは、指定する
正規表現
を、
\$\{.*\}
ではなく、
\$\{[^\}]*\}
にします。 複数の変数があるときでも正しく処理するようになります。
XML の Variable タグを変数にした辞書を返します
パスに関する変数か定義された辞書を返します
${ } を使った式を解析します
でも変数を一覧することができます。
g("${RootPath}") = "C:\Folder\A"
g("${Target}") = "A"
Assert g.Formula("${RootPath}") = "C:\Folder\A"
Assert g.Formula("${RootPath}") <> "C:\Folder\${Target}"
と異なり、変数の値に一致しても、変数に戻ることはありません。
<Variable name="${FullPath1}" value="..\File.txt" type="FullPathType"/>
XML の Variable タグの type 属性は、Type_ プロパティで参照できます。
path = t("C:\Folder")+"\Sub\Setting.xml"
base_path = GetParentFullPath( path )
Set root = LoadXML( path, Empty )
Set g = LoadVariableInXML( root, path )
Assert g.Formula("${FullPath1}") = t("C:\Folder")+"\ABC"
Assert g.Formula("${StepPath}") = "..\ABC"
Assert g.Formula("${ABC}") = "ABC"
Assert g.Formula("${FullPath2}") = "${FullPath1}\File.txt"
Assert g.Formula("${FullPath3}") = t("C:\Folder")+"\Sub\${StepPath}\File.txt"
Set file = OpenForWrite( "_out.xml", g_VBS_Lib.UTF_8 )
file.WriteLine "<?xml version=""1.0"" encoding=""UTF-8""?>"
file.WriteLine "<Root>"
file.WriteLine ""
For Each variable_name In Array( _
"${FullPath1}", "${StepPath}", "${ABC}", "${FullPath2}", "${FullPath3}" )
If not IsFullPath( g.Formula( variable_name ) ) Then
file.WriteLine "<Variable name="""+ variable_name +""" value="""+ _
g.Formula( variable_name ) +"""/>"
Else
file.WriteLine "<Variable name="""+ variable_name +""" value="""+ _
GetStepPath( g.Formula( variable_name ), base_path ) + _
""" type=""FullPathType""/>"
End If
Next
file.WriteLine ""
file.WriteLine "</Root>"
file = Empty
file.WriteLine "<Variable name=""${FullPath1}"" value="""+ _
g.Formula( "${FullPath1}" ) +""" type="""+ g.Type_( "${FullPath1}" ) +"""/>"
サンプル
FullPathType
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Variable name="${FullPath1}" value="..\ABC" type="FullPathType"/>
<Variable name="${StepPath}" value="..\ABC"/>
<Variable name="${ABC}" value="ABC"/>
<Variable name="${FullPath2}" value="${FullPath1}\File.txt"/>
<Variable name="${FullPath3}" value="${StepPath}\File.txt" type="FullPathType"/>
</Root>
サンプル
g("${F1}") = "C:\Folder1"
g("${F2}") = "C:\Folder2"
Assert g.GetFullPath( "File.txt", "C:\Folder1" ) = "C:\Folder1\File.txt"
Assert g.GetFullPath( "File.txt", "${F1}" ) = "C:\Folder1\File.txt"
Assert g.GetFullPath( "${F2}\File.txt", "${F1}" ) = "C:\Folder2\File.txt"
Assert g.GetFullPath( "File.txt", "${No}" ) '// Error
参考
→ Python - 数列 (range クラス)
Assert g("${ToCSV( %d, 1, 3 )}") = "1, 2, 3"
Assert g("${ToCSV( %d, 2, 5 )}") = "2, 3, 4, 5"
Assert g("${ToCSV( %d, 2, 5 )}") = "5, 4, 3, 2"
Assert g("${ToCSV( %02d, 1, 3 )}") = "01, 02, 03"
g("${N}") = "Num"
Assert g("${ToCSV( ${N} = %d, 1, 3 )}") = "Num = 1, Num = 2, Num = 3"
Assert g("${N} = ${ToCSV( %d, 1, 3 )}") = "Num = 1, 2, 3"
→ T_LazyDictionary.vbs
T_LazyDictionaryCSV
テスト
( ) の中のパラメーターは、
、開始の値、最後の値です。
C言語の printf 書式の中に、${ } 変数を記述できます。
( ) の中のパラメーターは、CSV としてパースされるので、" "で囲むこともできます。
Sub Main()
Set g = new LazyDictionaryClass
Set g("${GetObject()}") = GetRef( "My_GetObject" )
Set object = g("${GetObject( a,b )}")
Assert object.Name = " a,b "
Set g("${UpperCase()}") = GetRef( "My_UpperCase" )
g.Delegate = "UserDefined"
Assert g("before ${Upper( a,b )} after") = _
"before ( A,B ) after"
End Sub
Function My_GetObject( ref_Dictionary, in_FunctionName, in_Parameter )
Set object = new NameOnlyClass
object.Name = in_Parameter
Set My_GetObject = object
End Function
Function My_UpperCase( ref_Dictionary, in_FunctionName, in_Parameter )
Assert in_FunctionName = "${My_UpperCase()}"
Assert ref_Dictionary.Delegate = "UserDefined"
My_GetObject = "("+ UCase( in_Parameter ) +")"
End Function
Function LazyDictionaryFunction( ref_Dictionary as LazyDictionaryClass,
in_FunctionName as string, in_Parameter as string ) as Variant
関数は下記の型である必要があります。
LazyDictionaryClass で ${Function( parameters )} 形式を指定したときに呼び出す関数の型。
【引数】
ref_Dictionary
in_Parameter
LazyDictionaryClass のオブジェクト
括弧の中のすべてのパラメーター
Set g("${UpperCase()}") = GetRef( "UpperCase" )
コールバックする関数を設定するには、次のように記述します。
サンプル
${Function( parameters )} 形式を指定すると、アプリケーションが定義した関数を呼び出す、
または、VBScript で定義した関数をコールバックさせることができます。
Assert g("${UpperCase( abc, def )}") = "ABC, DEF"
UpperCase 関数をパラメーター abc, def で呼び出し、ABC, DEF が返されたことをチェックする
には、次のように記述します。
in_Parameter の中にあるそれぞれのパラメーターを取得するときは、
などを使ってください。
${Function( parameters )} を置き換えた後の値
返り値
in_FunctionName
関数名。 例:"${FunctionName()}"
ref_Dictionary の Delegate メンバー変数は、LazyDictionaryClass オブジェクトを生成
したユーザーが設定して、コールバック関数で参照することができます。
Type_
type
関連
は、変数の値を参照し、フル パスを返します。
ただし、スクリプトの中の LazyDictionaryClass のオブジェクト(下記の g)の特定が必要です。
←
▼
▲
<Variable name="${Var1}" value="ABC"/>
<Project path="C:\${Var1}.txt"/>
Set root = LoadXML( "Sample.xml", Empty )
Set variables = LoadVariableInXML( root, "Sample.xml" )
data = root.selectSingleNode( "Data" ).getAttribute( "data" )
Assert data ="${Var1}DEF"
data = variables( data )
Assert data = "ABCDEF"
Function LoadVariableInXML( in_RootXML_Element as IXMLDOMElement, in_FilePathOfXML as string )
as LazyDictionaryClass
XML の
【引数】
in_RootXML_Element
in_FilePathOfXML
in_RootXML_Element が書かれている XML ファイルのパス
サンプル
Sample.xml
スクリプト:
<Sample>
<Variable name="${Var1}" value="ABC"/>
<Variable name="${Var2}" value="XYZ"/>
<Data data="${Var1}DEF"/>
</Sample>
variables
<Variable name="${Var1}" value="ABC"/>
テスト
→ vbslib.vbs
ソース
→ T_LazyDictionary.vbs
variables
変数の定義の例:
T_LazyDictionaryXML
変数名は ${Var1} で、その値は ABC です。
変数を参照するときは、DOM API で値を取得した後で、評価(変数の展開を)する処理を書く
必要があります。(下記サンプル コードを参照)
type 属性を "FullPathType" にすると、value 属性を相対パスとして、変数を参照したときは
フル・パスが返ります。 通常、基準フォルダーは XML ファイルがあるフォルダーです。
<Sample>
<Variable name="${FullPath1}" value="..\File.txt" type="FullPathType"/>
<Variable name="${FullPath2}" value="${FullPath1}"/>
<Variable name="${ErrorPath}" value="${FullPath1}" type="FullPathType"/>
<Variable name="${SearchParent}" value="...\File.txt" type="FullPathType"/>
</Sample>
スクリプト:
Sample.xml
Set xml = new FilePathClass
xml.FilePath = "Sample.xml"
Set xml.Text = LoadXML( xml.FilePath, Empty )
Set variables = new_LazyDictionaryClass( xml )
base_path = GetParentFullPath( xml.FilePath )
Assert variables( "${FullPath1}" ) = GetFullPath( "..\File.txt", base_path )
Assert variables( "${FullPath2}" ) = GetFullPath( "..\File.txt", base_path )
Assert variables( "${ErrorPath}" ) = _
base_path +"\"+ GetFullPath( "..\File.txt", base_path )
'// Example: "C:\Folder\Sub\C:\Folder\File.txt"
Assert variables.Formula( "${ErrorPath}" ) = "C:\Folder\Sub\${ErrorPath}"
サンプル
${FullPath1}
XML に記述する value 属性は、相対パスを指定してください。 value 属性がフル パスの値を
持つ変数から始まるときは、type 属性に "FullPathType" を指定しないでください。
フル・パスに変換するタイミングは、new_LazyDictionaryClass 関数を呼び出したときで、
遅延評価ではありません。
${Var1}
2つの辞書を合成するときは、
を呼び出してください。
XML のルート要素オブジェクト、または、FilePathClass のオブジェクト
new_LazyDictionaryClass 関数の引数に FilePathClass のオブジェクトを指定すると、
FilePathClass::FilePath の親フォルダーを基準にします。 引数に文字列を指定した場合は、
相対パスの基準はカレント・フォルダーになります。 XML のルート要素オブジェクトは、
FilePathClass::Text に指定してください。
に設定すると、値をフル パスにすることができます。
value 属性を、ピリオド 3つから始めると、内部で
を呼び出して、親フォルダー
を探しにいきます。
<Variable name="${FullPath1}" value="..\File.txt" type="FullPathType"/>
type="FullPathType"
サンプル
返り値
遅延評価する辞書
値に
ことができます。
<Variable name="${A}" value="${USERPROFILE}\Document\A"/>
サンプル
USERPROFILE は、OS の環境変数の名前です。
<Variable name="${Desktop}" value="${USERPROFILE}\Desktop"/>
関連
Variable タグに対応した XML ファイルには、${ } 形式の変数の定義と、変数の参照を記述する
ことができます。
で、Variable タグによる変数定義をロードします。
変数の参照を記述できる場所は、XML ファイルの種類やアプリケーションによって異なります。
それぞれの仕様を確認してください。 たとえば、Project タグの path 属性に変数を指定できる
仕様の場合、以下のように記述できます。
${Var1}
変数の定義と参照の例:
こともできます。
によって管理されるため、遅延評価されます。
${ } 変数は、
変数の参照を記述できる場所には、
スクリプトの内部では、
変数の定義は、以下のように Variable タグを記述します。 ただし、name は、${ から始まり、} で
終えてください。 Variable タグは、XML の中のどこでも記述することができます。
path 属性は C:\ABC.txt になります。
または
${USERPROFILE}
${USERPROFILE}
${ } の中に OS の環境変数名を記述すると、その値を参照することができます。
変数を定義する Variable タグの value 属性や、${ } 変数を参照できる場所に、OS の環境変数の
参照を記述できます。
変数の参照を記述する場所によって値を変更するときは、
で定義してください。
${Var1}
${Var1}
手動で変数の展開をするときは、
が使えます。
<Variable name="${A}" value="${UpperCase( abc, def )}"/>
サンプル
参考
アプリケーションによっては、${ } の中に ( ) が付いた関数呼び出しを記述することができます。
で定義された変数を持つ、遅延評価する辞書を生成します。
ことができます。
<Project path="${UpperCase( C:\File.txt )"/>
→ vbslib_mini.vbs
思ったように展開されないときは、
を試してみてください